home *** CD-ROM | disk | FTP | other *** search
/ Giga Games 1 / Giga Games.iso / net / hack / 2_3 / do.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-20  |  11.2 KB  |  526 lines

  1. /*    SCCS Id: @(#)do.c    2.3    88/02/11
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3.  
  4. /* Contains code for 'd', 'D' (drop), '>', '<' (up, down) and 't' (throw) */
  5.  
  6. #include "hack.h"
  7.  
  8. extern struct obj *splitobj(), *addinv();
  9. extern boolean hmon();
  10. extern boolean level_exists[];
  11. extern struct monst youmonst;
  12. extern char *Doname();
  13. extern char *nomovemsg;
  14. int    identify();
  15. #ifdef KAA
  16. extern char *xname();
  17. #endif
  18.  
  19. dodrop() {
  20.     if(u.ugold)    return(drop(getobj("0$#", "drop")));
  21.     else        return(drop(getobj("0#", "drop")));
  22. }
  23.  
  24. static
  25. drop(obj) register struct obj *obj; {
  26.     if(!obj) return(0);
  27.     if(obj->olet == GOLD_SYM) {        /* pseudo object */
  28.         register long amount = OGOLD(obj);
  29.  
  30.         if(amount == 0)
  31.             pline("You didn't drop any gold pieces.");
  32. /* Fix bug with dropping huge amounts of gold read as negative    KAA */
  33.         else if(amount < 0) {
  34.             u.ugold += amount;
  35.     pline("The LRS would be very interested to know you have that much.");
  36.         } else {
  37.             /* uswallow test added by GAN 01/29/87 */
  38.             pline("You dropped %ld gold piece%s.",
  39.                  amount, plur(amount));
  40.             if(u.uswallow)
  41.                 (u.ustuck)->mgold += amount;
  42.             else {
  43.                 mkgold(amount, u.ux, u.uy);
  44.                 if(Invisible) newsym(u.ux, u.uy);
  45.             }
  46.         }
  47.         free((char *) obj);
  48.         return(1);
  49.     }
  50.     if(obj->owornmask & (W_ARMOR | W_RING | W_TOOL)){
  51.         pline("You cannot drop something you are wearing.");
  52.         return(0);
  53.     }
  54.     if(obj == uwep) {
  55.         if(uwep->cursed) {
  56.             pline("Your weapon is welded to your hand!");
  57.             return(0);
  58.         }
  59.         setuwep((struct obj *) 0);
  60.     }
  61. #ifdef WALKIES
  62.         if (obj->otyp == LEASH) {
  63.             register struct monst *mtmp = fmon;
  64.             while (mtmp && !mtmp->mleashed) mtmp = mtmp->nmon;
  65.             if (mtmp) {
  66.                 pline ("Your leash is tied around your hand.");
  67.                 return (0);
  68.             }
  69.         }
  70. #endif
  71. #ifdef SINKS
  72.     if((obj->olet == RING_SYM) && IS_SINK(levl[u.ux][u.uy].typ))
  73.         if (u.uswallow) {
  74.         freeinv(obj);
  75.         mpickobj(u.ustuck,obj);
  76.         return(1);
  77.         }
  78.         else {
  79.         dosinkring(obj);
  80.         return(1);
  81.         }
  82. #endif
  83.     pline("You dropped %s.", doname(obj));
  84.     dropx(obj);
  85.     return(1);
  86. }
  87.  
  88. /* Called in several places - should not produce texts */
  89. dropx(obj)
  90. register struct obj *obj;
  91. {
  92.     freeinv(obj);
  93.     dropy(obj);
  94. }
  95.  
  96. dropy(obj)
  97. register struct obj *obj;
  98. {
  99.     if(obj->otyp == CRYSKNIFE)
  100.         obj->otyp = WORM_TOOTH;
  101.     /* uswallow check done by GAN 01/29/87 */
  102.     if(u.uswallow)
  103.         mpickobj(u.ustuck,obj);
  104.     else  {
  105.         obj->ox = u.ux;
  106.         obj->oy = u.uy;
  107.         /* Blind check added by GAN 02/18/87 */
  108.         if(Blind)  {
  109. #ifdef KAA
  110.             if(obj->olet != ')')
  111. #endif
  112.                 obj->dknown = index("/=!?*",obj->olet) ? 0 : 1;
  113.             obj->known = 0;
  114.         }
  115.         obj->nobj = fobj;
  116.         fobj = obj;
  117.         if(Invisible) newsym(u.ux,u.uy);
  118.         subfrombill(obj);
  119.         stackobj(obj);
  120.     }
  121. }
  122.  
  123. /* drop several things */
  124. doddrop() {
  125.     return(ggetobj("drop", drop, 0));
  126. }
  127.  
  128. dodown()
  129. {
  130.     if(u.ux != xdnstair || u.uy != ydnstair) {
  131.         pline("You can't go down here.");
  132.         return(0);
  133.     }
  134.     if(u.ustuck) {
  135.         pline("You are being held, and cannot go down.");
  136.         return(1);
  137.     }
  138.     if(Levitation) {
  139.         pline("Your floating high above the stairs.");
  140.         return(0);
  141.     }
  142.  
  143.     goto_level(dlevel+1, TRUE);
  144.     return(1);
  145. }
  146.  
  147. doup()
  148. {
  149.     if(u.ux != xupstair || u.uy != yupstair) {
  150.         pline("You can't go up here.");
  151.         return(0);
  152.     }
  153.     if(u.ustuck) {
  154.         pline("You are being held, and cannot go up.");
  155.         return(1);
  156.     }
  157.     if(!Levitation && inv_weight() + 5 > 0) {
  158.         pline("Your load is too heavy to climb the stairs.");
  159.         return(1);
  160.     }
  161.  
  162.     goto_level(dlevel-1, TRUE);
  163.     return(1);
  164. }
  165.  
  166. goto_level(newlevel, at_stairs)
  167. register int newlevel;
  168. register boolean at_stairs;
  169. {
  170.     register fd;
  171.     register boolean up = (newlevel < dlevel);
  172.  
  173.     if(newlevel <= 0) done("escaped");    /* in fact < 0 is impossible */
  174.     if(newlevel > MAXLEVEL) newlevel = MAXLEVEL;    /* strange ... */
  175.     if(newlevel == dlevel) return;          /* this can happen */
  176.  
  177.     glo(dlevel);
  178. #ifdef DGK
  179.     /* Use O_TRUNC to force the file to be shortened if it already
  180.      * exists and is currently longer.
  181.      */
  182.     fd = open(lock, O_WRONLY | O_BINARY | O_CREAT | O_TRUNC, FMASK);
  183. #else
  184.     fd = creat(lock, FMASK);
  185. #endif
  186.     if(fd < 0) {
  187.         /*
  188.          * This is not quite impossible: e.g., we may have
  189.          * exceeded our quota. If that is the case then we
  190.          * cannot leave this level, and cannot save either.
  191.          * Another possibility is that the directory was not
  192.          * writable.
  193.          */
  194. #ifdef DGK
  195.         pline("Cannot create level file '%s'.", lock);
  196. #else
  197.         pline("A mysterious force prevents you from going %s.",
  198.             up ? "up" : "down");
  199. #endif
  200.         return;
  201.     }
  202.  
  203. #ifdef DGK
  204.     if (!savelev(fd, dlevel, COUNT)) {
  205.         (void) close(fd);
  206.         (void) unlink(lock);
  207.         pline("HACK is out of disk space for making levels!");
  208.         pline("You can save, quit, or continue playing.");
  209.         return;
  210.     }
  211. #endif
  212.     if(Punished) unplacebc();
  213.     u.utrap = 0;                /* needed in level_tele */
  214.     u.ustuck = 0;                /* idem */
  215.     keepdogs();
  216.     seeoff(1);
  217.     if(u.uswallow)                /* idem */
  218.         u.uswldtim = u.uswallow = 0;
  219.     flags.nscrinh = 1;
  220.     u.ux = FAR;                /* hack */
  221.     (void) inshop();            /* probably was a trapdoor */
  222.  
  223. #ifdef DGK
  224.     savelev(fd,dlevel, WRITE);
  225. #else
  226.     savelev(fd,dlevel);
  227. #endif
  228.     (void) close(fd);
  229.  
  230.     dlevel = newlevel;
  231.     if(maxdlevel < dlevel)
  232.         maxdlevel = dlevel;
  233.     glo(dlevel);
  234. #ifdef MSDOS
  235.     /* If the level has no where yet, it hasn't been made
  236.      */
  237.     if(!fileinfo[dlevel].where)
  238. #else
  239.     if(!level_exists[dlevel])
  240. #endif
  241.         mklev();
  242.     else {
  243.         extern int hackpid;
  244. #ifdef DGK
  245.         /* If not currently accessible, swap it in.
  246.          */
  247.         if (fileinfo[dlevel].where != ACTIVE)
  248.             swapin_file(dlevel);
  249.  
  250.         if((fd = open(lock, O_RDONLY | O_BINARY)) < 0) {
  251. #else
  252.         if((fd = open(lock,0)) < 0) {
  253. #endif
  254.             pline("Cannot open %s .", lock);
  255.             pline("Probably someone removed it.");
  256.             done("tricked");
  257.         }
  258.         getlev(fd, hackpid, dlevel);
  259.         (void) close(fd);
  260.     }
  261.  
  262.     if(at_stairs) {
  263.         if(up) {
  264.         u.ux = xdnstair;
  265.         u.uy = ydnstair;
  266.         if(!u.ux) {        /* entering a maze from below? */
  267.             u.ux = xupstair;    /* this will confuse the player! */
  268.             u.uy = yupstair;
  269.         }
  270. /* Remove bug which crashes with levitation/punishment  KAA */
  271.         if(Punished) {
  272.             if(!Levitation) 
  273.             pline("With great effort you climb the stairs.");
  274.             placebc(1);
  275.         }
  276.         } else {
  277.         u.ux = xupstair;
  278.         u.uy = yupstair;
  279.         if(inv_weight() + 5 > 0 || Punished){
  280.             pline("You fall down the stairs.");    /* %% */
  281.             losehp(rnd(3), "fall");
  282.             if(Punished) {
  283.                 if(uwep != uball && rn2(3)){
  284.                 pline("... and are hit by the iron ball.");
  285.                 losehp(rnd(20), "iron ball");
  286.                 }
  287.                 placebc(1);
  288.             }
  289.             selftouch("Falling, you");
  290.         }
  291.         }
  292.         { register struct monst *mtmp = m_at(u.ux, u.uy);
  293.           if(mtmp)
  294.         mnexto(mtmp);
  295.         }
  296.     } else {    /* trapdoor or level_tele */
  297.         do {
  298.         u.ux = rnd(COLNO-1);
  299.         u.uy = rn2(ROWNO);
  300.         } while(levl[u.ux][u.uy].typ != ROOM ||
  301.             m_at(u.ux,u.uy));
  302.         if(Punished){
  303.         if(uwep != uball && !up /* %% */ && rn2(5)){
  304.             pline("The iron ball falls on your head.");
  305.             losehp(rnd(25), "iron ball");
  306.         }
  307.         placebc(1);
  308.         }
  309.         selftouch("Falling, you");
  310.     }
  311.     (void) inshop();
  312.     initrack();
  313.  
  314.     losedogs();
  315.     { register struct monst *mtmp;
  316.       if(mtmp = m_at(u.ux, u.uy)) mnexto(mtmp);    /* riv05!a3 */
  317.     }
  318.     flags.nscrinh = 0;
  319.     setsee();
  320.     seeobjs();    /* make old cadavers disappear - riv05!a3 */
  321.     docrt();
  322.     pickup(1);
  323.     read_engr_at(u.ux,u.uy);
  324. }
  325.  
  326. donull() {
  327.     return(1);    /* Do nothing, but let other things happen */
  328. }
  329.  
  330. #if defined(KAA) && defined(KOPS)
  331. wipeoff()
  332. {
  333.     if(u.ucreamed < 4)    u.ucreamed = 0;
  334.     else            u.ucreamed -= 4;
  335.     if(u.ucreamed > 0)  {
  336.         Blinded -= 4;
  337.         if(Blind <= 1) {
  338.             pline("You've got the glop off.");
  339.             u.ucreamed = 0;
  340.             Blinded = 1;
  341.             return(0);
  342.         }
  343.         return(1);        /* still busy */
  344.     }
  345.     pline("Your face feels clean now.");
  346.     u.ucreamed = 0;
  347.     return(0);
  348. }
  349.     
  350. dowipe()
  351. {
  352.     if(u.ucreamed)  {
  353. #ifdef DGKMOD
  354.         set_occupation(wipeoff, "wiping off your face", 0);
  355. #else
  356.         occupation = wipeoff;
  357.         occtxt = "wiping off your face";
  358. #endif
  359.         return(1);
  360.     }
  361.     pline("Your face is already clean.");
  362.     return(1);
  363. }
  364. #endif
  365.  
  366. /* split obj so that it gets size num */
  367. /* remainder is put in the object structure delivered by this call */
  368. struct obj *
  369. splitobj(obj, num) register struct obj *obj; register int num; {
  370. register struct obj *otmp;
  371.     otmp = newobj(0);
  372.     *otmp = *obj;        /* copies whole structure */
  373.     otmp->o_id = flags.ident++;
  374.     otmp->onamelth = 0;
  375.     obj->quan = num;
  376.     obj->owt = weight(obj);
  377.     otmp->quan -= num;
  378.     otmp->owt = weight(otmp);    /* -= obj->owt ? */
  379.     obj->nobj = otmp;
  380.     if(obj->unpaid) splitbill(obj,otmp);
  381.     return(otmp);
  382. }
  383.  
  384. more_experienced(exp,rexp)
  385. register int exp, rexp;
  386. {
  387.     extern char pl_character[];
  388.  
  389.     u.uexp += exp;
  390.     u.urexp += 4*exp + rexp;
  391.     if(exp) flags.botl = 1;
  392.     if(u.urexp >= ((pl_character[0] == 'W') ? 1000 : 2000))
  393.         flags.beginner = 0;
  394. }
  395.  
  396. set_wounded_legs(side, timex)
  397. register long side;
  398. register int timex;
  399. {
  400.     if(!Wounded_legs || (Wounded_legs & TIMEOUT))
  401.         Wounded_legs |= side + timex;
  402.     else
  403.         Wounded_legs |= side;
  404. }
  405.  
  406. heal_legs()
  407. {
  408.     if(Wounded_legs) {
  409.         if((Wounded_legs & BOTH_SIDES) == BOTH_SIDES)
  410.             pline("Your legs feel somewhat better.");
  411.         else
  412.             pline("Your leg feels somewhat better.");
  413.         Wounded_legs = 0;
  414.     }
  415. }
  416.  
  417. #ifdef SINKS
  418. trycall(obj)
  419. register struct obj *obj;
  420. {
  421.     if(!objects[obj->otyp].oc_name_known &&
  422.        !objects[obj->otyp].oc_uname)
  423.        docall(obj);
  424. }
  425.  
  426. dosinkring(obj)  /* obj is a ring being dropped over a kitchen sink */
  427. register struct obj *obj;
  428. {
  429. register struct obj *otmp,*otmp2;
  430. register short eaten;
  431.     pline("You drop %s down the drain.", doname(obj));
  432.     switch(obj->otyp) {
  433.         case RIN_ADORNMENT:  {
  434.         pline("The faucets flash brightly for a moment.");
  435.         trycall(obj);
  436.         break;
  437.         }
  438.         case RIN_REGENERATION:  {
  439.         pline("The sink looks as good as new.");
  440.         trycall(obj);
  441.         break;
  442.         }
  443.         case RIN_SEARCHING:
  444.         break;
  445.         case RIN_SEE_INVISIBLE:
  446.         break;
  447.         case RIN_STEALTH:  {
  448.         pline("The sink seems to blend into the floor for a moment.");
  449.         trycall(obj);
  450.         break;
  451.         }
  452.         case RIN_LEVITATION:  {
  453.         pline("The sink quivers upward for a moment.");
  454.         trycall(obj);
  455.         break;
  456.         }
  457.         case RIN_POISON_RESISTANCE:
  458.         break;
  459.         case RIN_AGGRAVATE_MONSTER:
  460.         break;
  461.         case RIN_HUNGER:  {
  462.         eaten = 0;
  463.         for(otmp=fobj; otmp; otmp=otmp2) {
  464.             otmp2 = otmp->nobj;
  465.             if(otmp->ox == u.ux && otmp->oy == u.uy)
  466.             if(!Punished ||
  467.                 (otmp->otyp != HEAVY_IRON_BALL && otmp->otyp != IRON_CHAIN)) {
  468.                 eaten++;
  469.                 pline("Suddenly, %s vanishes from the sink!",doname(otmp));
  470.                 delobj(otmp);
  471.             }
  472.         }
  473.         if(eaten)
  474.             trycall(obj);
  475.         break;
  476.         }
  477.         case RIN_FIRE_RESISTANCE:  {
  478.         pline("The hot water faucet flashes brightly for a moment.");
  479.         trycall(obj);
  480.         break;
  481.         }
  482.         case RIN_COLD_RESISTANCE:  {
  483.         pline("The cold water faucet flashes brightly for a moment.");
  484.         trycall(obj);
  485.         break;
  486.         }
  487.         case RIN_PROTECTION_FROM_SHAPE_CHAN:  {
  488.         pline("The sink momentarily looks nothing like a fountain.");
  489.         trycall(obj);
  490.         break;
  491.         }
  492.         case RIN_CONFLICT:
  493.         break;
  494.         case RIN_GAIN_STRENGTH:
  495.         break;
  496.         case RIN_INCREASE_DAMAGE:
  497.         break;
  498.         case RIN_PROTECTION:
  499.         break;
  500.         case RIN_WARNING:  {
  501.         pline("The sink glows white for a moment.");
  502.         trycall(obj);
  503.         break;
  504.         }
  505.         case RIN_TELEPORTATION:    /* fall through */
  506.         case RIN_TELEPORT_CONTROL:  {
  507.         pline("The sink momentarily vanishes.");
  508.         trycall(obj);
  509.         break;
  510.         }
  511.         case RIN_POLYMORPH:        /* fall through */
  512.         case RIN_POLYMORPH_CONTROL:  {
  513.         pline("The sink momentarily looks like a fountain.");
  514.         trycall(obj);
  515.         break;
  516.         }
  517.     }
  518.     if (!rn2(20)) {
  519.         pline("The sink backs up, leaving %s.", doname(obj));
  520.         dropx(obj);
  521.     }
  522.     else
  523.         useup(obj);
  524. }
  525. #endif
  526.